#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Unit tests for clocks.py
import unittest
import clocks
import cPickle
import generic_mock

class TestClock(unittest.TestCase):
    
    def setUp(self):
        self.comm_channel_ = generic_mock.GenericMock()
        self.comm_channel_.StubForTesting('get_pid', lambda: 1)
        self.clock_ = clocks.clock(self.comm_channel_)

    def testConstructor(self):
        self.assertEqual(self.clock_.get_pid(), 1)

    def testPrintOutput(self):
        self.clock_.print_output('dummy text')
        self.assertEqual(
            self.comm_channel_, 
            [('print_output', ('dummy text',), {})])

    def testCloseChannel(self):
        self.clock_.close_channel(2)
        self.assertEqual(
            self.comm_channel_, 
            [('close_channel', (2,), {})])

    def testSendMessage(self):
        self.clock_.send_message(2, 'msg')
        self.assertEqual(
            self.comm_channel_, 
            [('send_message', (2, 'msg'), {})])

    def testRecvMessage(self):
        self.comm_channel_.StubForTesting('recv_message',
                                          lambda: 'message')
        self.assertEqual(self.clock_.recv_message(), 
                         'message')
    
    def testNetworkSize(self):
        self.comm_channel_.StubForTesting('network_size',
                                          lambda: 5)
        self.assertEqual(self.clock_.network_size(), 5) 
        
    def testGetPid(self):
        self.comm_channel_.StubForTesting('get_pid',
                                          lambda: 1)
        self.assertEqual(self.clock_.get_pid(), 1)

    def testGetHosts(self):
        self.comm_channel_.StubForTesting('get_hosts',
                                          lambda: {1: ('127.0.0.1', 1)})
        self.assertEqual(self.clock_.get_hosts(), {1: ('127.0.0.1', 1)})
        
    def testChannelState(self):
        self.comm_channel_.StubForTesting('channel_state',
                                          lambda x: True)
        self.assertEqual(self.clock_.channel_state(1), True)

    def testClose(self):
        self.clock_.close()
        self.assertEqual(self.comm_channel_, [('close', (), {})])
            

class TestLamportClock(unittest.TestCase):
    
    def setUp(self):
        self.comm_channel_ = generic_mock.GenericMock()
        self.comm_channel_.StubForTesting('get_pid', lambda: 1)
        self.clock_ = clocks.lamport_clock(self.comm_channel_)
        
    def testConstructor(self):
        self.assertEqual(self.clock_.get_pid(), 1)
        self.assertEqual(self.clock_.clock, 0)

    def testGetClock(self):
        self.clock_.clock = 5
        self.assertEqual(self.clock_.get_clock(), 5)

    def testIncreaseClock(self):
        self.clock_.clock = 5
        self.clock_.increase_clock()
        self.assertEqual(self.clock_.clock, 6)

    def testSendMessage(self):
        self.clock_.clock = 5
        self.clock_.send_message(2, 'msg')
        self.assertEqual(self.clock_.clock, 6)
        self.assertEqual(
            self.comm_channel_, 
            [('send_message', (2, ('msg', 6)), {})])

    def testRecvMessage(self):
        self.comm_channel_.StubForTesting(
            'recv_message', lambda: (3, ('msg', 5)))
        self.assertEqual(self.clock_.recv_message(),
                         (3, 'msg'))
        self.assertEqual(self.clock_.clock, 6)

        self.clock_.clock = 10
        self.assertEqual(self.clock_.recv_message(),
                         (3, 'msg'))
        self.assertEqual(self.clock_.clock, 11)


if __name__ == '__main__':
    unittest.main()
